package com.swb.alibaba.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Objects;

/**
 * <p>文件  CommandLineUtil</p>
 * <p>时间  2021-06-30 22:56:58</p>
 *
 * @author swb
 */
public class CommandLineUtil {
    private static final Logger log = LoggerFactory.getLogger(CommandLineUtil.class);

    public CommandLineUtil() {
    }

    public static CommandLineUtil.ExecuteResult execute(String command) throws IOException, InterruptedException {
        Process p = exec(command);
        boolean isError = false;
        StringBuilder stdo = new StringBuilder();
        StringBuilder stder = new StringBuilder();
        BufferedReader stdout = new BufferedReader(getStdout(p));
        BufferedReader stderr = new BufferedReader(getStderr(p));

        String line;
        while((line = stdout.readLine()) != null) {
            stdo.append(line).append("\n");
        }

        stdout.close();

        while((line = stderr.readLine()) != null) {
            stder.append(line).append("\n");
            isError = true;
        }

        stderr.close();
        p.waitFor();
        String stdos = stdo.toString();
        String stdors = stder.toString();
        log.debug(stdos);
        if (isError) {
            log.error(stdors);
        }

        return new CommandLineUtil.ExecuteResult(isError, stdos, stdors);
    }

    public static Process exec(String command) throws IOException {
        Runtime runtime = Runtime.getRuntime();
        log.debug("Execute command {}", command);
        return runtime.exec(command);
    }

    public static InputStreamReader getStdout(Process p) {
        return new InputStreamReader(p.getInputStream());
    }

    public static InputStreamReader getStderr(Process p) {
        return new InputStreamReader(p.getErrorStream());
    }

    public static class ExecuteResult {
        private boolean error;
        private String stdout;
        private String stderr;

        public ExecuteResult(boolean error, String stdout, String stderr) {
            this.error = error;
            this.stdout = stdout;
            this.stderr = stderr;
        }

        public boolean isError() {
            return this.error;
        }

        public String getStdout() {
            return this.stdout;
        }

        public String getStderr() {
            return this.stderr;
        }

        public void setError(boolean error) {
            this.error = error;
        }

        public void setStdout(String stdout) {
            this.stdout = stdout;
        }

        public void setStderr(String stderr) {
            this.stderr = stderr;
        }

        @Override
        public boolean equals(Object o) {
            if (o == this) {
                return true;
            } else if (!(o instanceof CommandLineUtil.ExecuteResult)) {
                return false;
            } else {
                CommandLineUtil.ExecuteResult other = (CommandLineUtil.ExecuteResult)o;
                if (!other.canEqual(this)) {
                    return false;
                } else if (this.isError() != other.isError()) {
                    return false;
                } else {
                    Object this$stdout = this.getStdout();
                    Object other$stdout = other.getStdout();
                    if (this$stdout == null) {
                        if (other$stdout != null) {
                            return false;
                        }
                    } else if (!this$stdout.equals(other$stdout)) {
                        return false;
                    }

                    Object this$stderr = this.getStderr();
                    Object other$stderr = other.getStderr();
                    if (this$stderr == null) {
                        if (other$stderr != null) {
                            return false;
                        }
                    } else if (!this$stderr.equals(other$stderr)) {
                        return false;
                    }

                    return true;
                }
            }
        }

        protected boolean canEqual(Object other) {
            return other instanceof CommandLineUtil.ExecuteResult;
        }

        @Override
        public String toString() {
            return "CommandLineUtil.ExecuteResult(error=" + this.isError() + ", stdout=" + this.getStdout() + ", stderr=" + this.getStderr() + ")";
        }
    }
}
